﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace SqlMonitoring.Core.Logging
{
    public sealed class Logging
    {
        private static volatile Logging instance;
        private static object syncRoot = new Object();
        private static SourceLevels _logMode = SourceLevels.Verbose;
        private static int _indentLevel = 0;
        private static int _indentSize = 2;
        
        private static TraceSource ts = new TraceSource("Log");
 
        //nonstatic part
        public Logging() 
        {
        }

        public void Error(string message, Exception e = null, int id = 0)
        {
            //TODO: completly use e in message below.            
            Log(TraceEventType.Error, message, id);
        }
        
        public void Fatal(string message, Exception e = null, int id = 0)
        {
            //TODO: completly use e in message below.
            Log(TraceEventType.Critical, message, id);
        }

        public void Debug(string message, int id = 0)
        {
            LogInformation(message, id);
        }

        public void Warn(string message, int id = 0)
        {
            Log(TraceEventType.Warning, message, id);
        }

        public void Info(string message, int id = 0)
        {
            Log(TraceEventType.Information, message, id);
        }
        //--nonstatic part

        //static part
        private static void SetIndent()
        {
            Trace.IndentLevel = _indentLevel;
            Trace.IndentSize = _indentSize;
        }

        public static int IndentSize
        {
            get { return Logging._indentSize; }
            set
            {
                int x = 1;
                if (value > x) x = value;
                Logging._indentSize = x;
            }
        }

        public static int IndentLevel
        {
            get { return Logging._indentLevel; }
            set
            {
                int x = 0;
                if (value > x) x = value;
                Logging._indentLevel = x;
            }
        }

        public static SourceLevels LogMode
        {
            get { return _logMode; }
            set { _logMode = value; }
        }

        public static Logging Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                            instance = new Logging();
                    }
                }
                return instance;
            }
        }

        public static void Indent()
        {
            _indentLevel++;
            SetIndent();
        }

        public static void Unindent()
        {
            _indentLevel--;
            SetIndent();
        }

        public static void LogIf(bool condition, TraceEventType eventType, string message, int id = 0)
        {
            if (condition)
            {
                Log(eventType, message, id);
            }
        }

        public static void Log(TraceEventType eventType, string message, int id = 0)
        {
            ts.TraceEvent(eventType, id, message);
        }

        public static void LogError(string message, int id = 0)
        {
            Log(TraceEventType.Error, message, id);
        }
        public static void LogWarning(string message, int id = 0)
        {
            Log(TraceEventType.Warning, message, id);
        }
        public static void LogInformation(string message, int id = 0)
        {
            Log(TraceEventType.Information, message, id);
        }

        public static void LogErrorIf(bool condition, string message, int id = 0)
        {
            LogIf(condition, TraceEventType.Error, message, id);
        }
        public static void LogWarningIf(bool condition, string message, int id = 0)
        {
            LogIf(condition, TraceEventType.Warning, message, id);
        }
        public static void LogInformationIf(bool condition, string message, int id = 0)
        {
            LogIf(condition, TraceEventType.Information, message, id);
        }

        //--static part
    }   
}
